package com.motu.monstercity.server.game.logichandler;

import com.motu.data.UserLoginDevice;
import com.motu.monstercity.module.common.network.RequestParam;
import com.motu.monstercity.module.common.redis.RedisKey;
import com.motu.monstercity.protocol.Common.PBUserData;
import com.motu.monstercity.protocol.CsGameSystem;
import com.motu.monstercity.protocol.CsGameSystem.CSGameSystemInitRequest;
import com.motu.monstercity.protocol.CsGameSystem.CSGameSystemInitResponse;
import com.motu.monstercity.server.game.log.ThinkingDataManager;
import com.motu.monstercity.server.game.logic.GameUser;
import com.motu.monstercity.server.game.logic.SystemManager;
import com.motu.monstercity.server.game.base.ProtoDataUtils;
import com.motu.monstercity.server.game.logic.*;
import com.motu.monstercity.server.game.userdata.UserAct;
import com.motu.monstercity.server.game.userdata.UserExtInfo;
import com.motu.monstercity.server.game.userdata.UserInfo;
import com.motu.vertx.module.utility.redis.RedisTools;
import com.motu.vertx.module.utility.toolset.ErrorWord;
import com.motu.vertx.module.utility.toolset.TimeUtils;
import com.motu.vertx.module.utility.toolset.Tool;
import io.vertx.core.Future;
import io.vertx.core.json.JsonObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;

public class SystemHandler {
    private final static Logger logger = LoggerFactory.getLogger(SystemHandler.class);

    // CMD_GAME_SYSTEM_INIT = 70301; //初始化
    public static Object CMD_GAME_SYSTEM_INIT(RequestParam clientParam) throws Exception {
        CSGameSystemInitRequest request = CSGameSystemInitRequest.parseFrom(clientParam.getData());
        CSGameSystemInitResponse.Builder response = CSGameSystemInitResponse.newBuilder();
        long userId = clientParam.getUserId();

        logger.info("###handleGameInit userId:" + userId);
        long sTime = System.currentTimeMillis();
        boolean isNoLoadAll = request.getIsNoLoadAll();// 客户端reload 时，上传true,表示不下发全部，比如建筑的摆放数据就不会下发

        PBUserData.Builder pbUserData = response.getUserBuilder();
        UserInfo userInfo = GameUser.getUserInfo(userId);
        UserExtInfo userExtInfo = GameUser.getUserExtInfo(userId);
		UserLoginDevice userLoginDevice = GameUser.getUserLoginDevice(userId);// 用户登录设备信息

        if (GameUser.isBanned(userExtInfo)) {
            return ErrorWord.BANNED_ACCOUNT;// 帐号被封
        }

		boolean isFirstLogin = userInfo.getLoginTime() == 0;// 是否首次登录
		boolean isFirstLoginToday = !TimeUtils.isToday(userInfo.getLoginTime());// 是否今天第一次登录

        //设置登陆账号类型和登陆账号ID
        if (!Tool.isEmpty(request.getLoginAccountid())) {
            userExtInfo.putLoginAccountId(request.getLoginAccountid());
            userExtInfo.putLoginAccountType(request.getLoginAccounttype());
        }

        // 设置mob和fcm推送标记
        if (!Tool.isEmpty(request.getMobid())) {
            userExtInfo.putMobId(request.getMobid());
        }
        if (!Tool.isEmpty(request.getFcmToken())) {
            userExtInfo.putFcmToken(request.getFcmToken());
        }


        // 更新客户端版本号
        userExtInfo.putClientVersion(request.getClientVersion());
		if (clientParam.getLanguage() > 0){
			userInfo.putLanguage(clientParam.getLanguage());
			userExtInfo.putLanguage(clientParam.getLanguage());
		}


        //更新数数sdk的distinct_id
        String timezone = userLoginDevice.getTimeZone();
        if (!Tool.isEmpty(timezone)) {
            userExtInfo.putTimezone(timezone);
            userInfo.putTimezone(timezone);
        }

        String distinct_id = userLoginDevice.getDistinctId();
        if (!Tool.isEmpty(distinct_id)) {
            //更新数数sdk的distinct_id
            userExtInfo.putDistinctId(distinct_id);
            userInfo.putDistinctId(distinct_id);
        }
      

        //注册数据和注册事件必须是服务端发送的第一个事件，所以代码需要放到这里
        String isOldRole = SystemManager.isOldRole(userLoginDevice.getDeviceId());//判断是否滚服
        ThinkingDataManager.pushUserRegisterData(userInfo,userLoginDevice,userExtInfo.getRegisterTime(),TimeUtils.getCurTime(),isOldRole,userInfo.getUserName());

		// 处理玩家首次登录逻辑
		if (isFirstLogin){
			SystemManager.doFirstLogin(pbUserData, userInfo, userExtInfo, userLoginDevice,isOldRole);
		}

        // 处理玩家登录逻辑（避免reload init 同时执行,需要加锁）
        String lockKey = RedisKey.getUserInitKey(userId);
        boolean init = Future.await(RedisTools.setnx(lockKey, "1"));
        if (init){
            try {
				SystemManager.doLogin(pbUserData, userInfo, userExtInfo, userLoginDevice);
            } finally {
                // 释放锁
                Future.await(RedisTools.del(lockKey));
            }
        } else{
            logger.warn("CMD_GAME_SYSTEM_INIT lock userid:" + userId);
        }

		userInfo.updateQueueNow();// 登录时间需要立即更新
		userExtInfo.update();

		// 下发客户端数据
        SystemManager.loadInitUserData(pbUserData, userInfo, userExtInfo, isNoLoadAll);// 加载背包,伙伴等用户数据
        SystemManager.loadInitSystemData(pbUserData, userInfo, userExtInfo);// 客户端开关配置,参数配置,服务器信息等系统参数数据
		SystemManager.loadInitActData(pbUserData, userInfo, userExtInfo);// 加载活动相关的数据，如比较简单一次性的固定活动，后台配置的活动，比较复杂的活动，循环活动等

		// 把登录可以异步处理的逻辑放到GameInitVerticle中去处理（例如红点，数据上报等）
		JsonObject message = new JsonObject();
		message.put("userId", userId);
		message.put("firstLogin", isFirstLogin);// 首次登录
		message.put("firstLoginToday", isFirstLoginToday);//今天是否第一次登录
        message.put("clientVersion", request.getClientVersion());// 客户端版本号
        message.put("packageVersion", request.getPackageVersion());// 客户端整包版本号
		SystemManager.noticeGameInit(message);

        long initTime = (System.currentTimeMillis() - sTime);
		logger.warn("######## system.init time：" + initTime + " userId:" + userId);
        return response;
    }

    // CMD_GAME_SYSTEM_RELOAD = 70303; //隔天重置
    public static Object CMD_GAME_SYSTEM_RELOAD(RequestParam clientParam) throws Exception {
        long userId = clientParam.getUserId();

		JsonObject message = new JsonObject();
		message.put("userId", userId);
		message.put("isReload", true);
//        SystemManager.noticeGameInit(message);
        UserInfo userInfo = GameUser.getUserInfo(userId);
        CsGameSystem.CSGameSystemRedPointResponse.Builder builder = CsGameSystem.CSGameSystemRedPointResponse.newBuilder();
        IapManager.checkRedPoint(userInfo, builder);
        return null;
    }
}
